home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Software of the Month Club / Amiga General Interest Volume 220 (1995)(SOMC)(Disk 2 of y)[SMCxxxC30Ix].zip / Amiga General Interest Volume 220 (1995)(SOMC)(Disk 2 of y)[SMCxxxC30Ix].adf / Typeface / Source / preview.c < prev    next >
C/C++ Source or Header  |  1995-10-01  |  14KB  |  513 lines

  1. /*******************/
  2. /*           */
  3. /* Font Previewing */
  4. /*           */
  5. /*******************/
  6.  
  7. #include "Typeface.h"
  8.  
  9. struct Window *PreviewWnd;
  10. struct ClipboardHandle *Clip, *Undo;
  11. Object *PreviewWndObj, *PreviewStr, *PreviewScroll;
  12. UBYTE *PreviewFont;
  13.  
  14. struct TextFont *tfh;
  15. struct NewMenu PreviewMenus[] = { PROJECT_MENU,FONT_MENU,PREVIEW_MENU,End };
  16.  
  17. extern struct Screen *Screen;
  18. extern struct MsgPort *WndMsgPort;
  19. extern struct Character CharBuffer[257];
  20. extern struct Window *SaveWnd;
  21. extern Object *SaveWndObj;
  22. extern ULONG FirstChar, LastChar;
  23.  
  24. void OpenPreviewWnd(void)
  25. {
  26. Object *all, *cancel, *update, *clear;
  27.  
  28.   if (PreviewWnd)
  29.   {
  30.     WindowToFront(PreviewWnd);
  31.     ActivateWindow(PreviewWnd);
  32.     SetPreviewFont();
  33.     SetPreviewScroller();
  34.     ActivateGadget(PreviewStr,PreviewWnd,NULL);
  35.   }
  36.   else
  37.   {
  38.     if (PreviewWndObj == NULL)
  39.     {
  40.       Clip = OpenClipboard(PRIMARY_CLIP);
  41.       Undo = OpenClipboard(1);
  42.       SetupMenus(PreviewMenus);
  43.       PreviewWndObj = WindowObject,
  44.     WINDOW_Screen,Screen,
  45.     WINDOW_SharedPort,WndMsgPort,
  46.     WINDOW_MenuStrip,PreviewMenus,
  47.     WINDOW_Title,GetString(msgPreviewTitle),
  48.     WINDOW_HelpFile,NAME".guide",
  49.     WINDOW_HelpNode,"preview",
  50.     WINDOW_ScaleWidth,70,
  51.     WINDOW_ScaleHeight,70,
  52.     WINDOW_SmartRefresh,TRUE,
  53.     WINDOW_CloseOnEsc,TRUE,
  54.     WINDOW_MasterGroup,
  55.       VGroupObject,
  56.         HOffset(SizeX(8)),VOffset(SizeY(4)),Spacing(SizeY(4)),
  57.         GROUP_BackFill,SHINE_RASTER,
  58.         StartMember,
  59.           HGroupObject,
  60.         HOffset(SizeX(8)),VOffset(SizeY(4)),
  61.         ButtonFrame,
  62.         FRM_Recessed,TRUE,
  63.         StartMember,
  64.           PreviewStr = ExternalObject,
  65.             EXT_Class,TEXTFIELD_GetClass(),
  66.             EXT_NoRebuild,TRUE,
  67.             TEXTFIELD_BlockCursor,TRUE,
  68.             TEXTFIELD_Border,TEXTFIELD_BORDER_DOUBLEBEVEL,
  69.             TEXTFIELD_PassCommand,TRUE,
  70.             TEXTFIELD_NonPrintChars,TRUE,
  71.             TEXTFIELD_ClipStream,Clip,
  72.             TEXTFIELD_UndoStream,Undo,
  73.             GA_ID,ID_PREVIEWSTR,
  74.           EndObject,
  75.         EndMember,
  76.         StartMember,
  77.           PreviewScroll = VertScroller(NULL,0,0,0,ID_PREVIEWSCROLL),
  78.           FixMinWidth,
  79.         EndMember,
  80.           EndObject,
  81.         EndMember,
  82.         StartMember,
  83.           HGroupObject,
  84.         Spacing(SizeX(8)),
  85.         EqualWidth,
  86.         StartMember,
  87.           update = KeyButton(GetString(gadgUpdate),ID_UPDATE),
  88.         EndMember,
  89.         StartMember,
  90.           all = KeyButton(GetString(gadgShowAll),ID_ALL),
  91.         EndMember,
  92.             StartMember,
  93.           clear = KeyButton(GetString(gadgClear),ID_CLEAR),
  94.         EndMember,
  95.             StartMember,
  96.           cancel = KeyButton(GetString(gadgCancel),ID_CANCEL),
  97.         EndMember,
  98.           EndObject,
  99.           FixMinHeight,
  100.         EndMember,
  101.       EndObject,
  102.     EndObject;
  103.       if (PreviewWndObj == NULL) ErrorCode(NEWWINDOW);
  104.       SetLabelKey(PreviewWndObj,update,gadgUpdate);
  105.       SetLabelKey(PreviewWndObj,all,gadgShowAll);
  106.       SetLabelKey(PreviewWndObj,clear,gadgClear);
  107.       SetLabelKey(PreviewWndObj,cancel,gadgCancel);
  108.     }
  109.     SetPreviewFont();
  110.     if ((PreviewWnd = WindowOpen(PreviewWndObj)) == NULL)
  111.       ErrorCode(OPENWINDOW);
  112.     SetPreviewScroller();
  113.     ActivateGadget(PreviewStr,PreviewWnd,NULL);
  114.   }
  115. }
  116.  
  117. void ClosePreviewWnd(BOOL all)
  118. {
  119.   ClrWindowClose(&PreviewWndObj,&PreviewWnd);
  120.   if (all)
  121.   {
  122.     ClrDisposeObject(&PreviewWndObj);
  123.     if (Clip) { CloseClipboard(Clip); Clip = NULL; }
  124.     if (Undo) { CloseClipboard(Undo); Undo = NULL; }
  125.     if (PreviewFont) { FreeVec(PreviewFont); PreviewFont = NULL; }
  126.   }
  127. }
  128.  
  129. void SetPreviewFont()
  130. {
  131. ULONG fchar, lchar;
  132. UBYTE *oldfont;
  133.  
  134.   oldfont = PreviewFont;
  135.   fchar = FirstChar;
  136.   lchar = LastChar;
  137.   FirstChar = 0;
  138.   LastChar = 255;
  139.   PreviewFont = SaveFont(TRUE,TRUE);
  140.   FirstChar = fchar;
  141.   LastChar = lchar;
  142.   if (PreviewWnd)
  143.   {
  144.     SetGadgetAttrs(PreviewStr,PreviewWnd,NULL,
  145.       TEXTFIELD_TextFont,PreviewFont ? tfh : NULL,TAG_DONE);
  146.   }
  147.   else
  148.   {
  149.     SetAttrs(PreviewStr,
  150.       TEXTFIELD_TextFont,PreviewFont ? tfh : NULL,TAG_DONE);
  151.   }
  152.   if (oldfont) FreeVec(oldfont);
  153. }
  154.  
  155. void PreviewMsgs(ULONG code)
  156. {
  157. ULONG top;
  158.  
  159.   switch (code)
  160.   {
  161.     case ID_CLEAR:
  162.       SetGadgetAttrs(PreviewStr,PreviewWnd,NULL,
  163.     TEXTFIELD_Text,"",TAG_DONE);
  164.       ActivateGadget(PreviewStr,PreviewWnd,NULL);
  165.       break;
  166.     case ID_ALL:
  167.       PreviewAll();
  168.       break;
  169.     case ID_UPDATE:
  170.       SetPreviewFont();
  171.       break;
  172.     case ID_PREVIEWSCROLL:
  173.       GetAttr(PGA_Top,PreviewScroll,&top);
  174.       SetGadgetAttrs(PreviewStr,PreviewWnd,NULL,
  175.     TEXTFIELD_Top,top,TAG_DONE);
  176.       break;
  177.     case ID_PREVIEWSTR:
  178.       SetPreviewScroller();
  179.       break;
  180.     default:
  181.       SharedMsgs(code,NULL);
  182.       break;
  183.   }
  184. }
  185.  
  186. void SetPreviewScroller()
  187. {
  188. ULONG lines,visible,top;
  189.  
  190.   GetAttr(TEXTFIELD_Lines,PreviewStr,&lines);
  191.   GetAttr(TEXTFIELD_Visible,PreviewStr,&visible);
  192.   GetAttr(TEXTFIELD_Top,PreviewStr,&top);
  193.   SetGadgetAttrs(PreviewScroll,PreviewWnd,NULL,
  194.     PGA_Total,lines,
  195.     PGA_Visible,visible,
  196.     PGA_Top,top,TAG_DONE);
  197. }
  198.  
  199. #define PREVIEW_WIDTH 32
  200.  
  201. void PreviewAll(void)
  202. {
  203. int i,j;
  204. char listtext[((PREVIEW_WIDTH+1)*(256/PREVIEW_WIDTH))+1];
  205.  
  206.   for (i = 0; i < 256/PREVIEW_WIDTH; i++)
  207.   {
  208.     for (j = 0; j < PREVIEW_WIDTH; j++)
  209.     {
  210.       switch ((i*PREVIEW_WIDTH)+j)
  211.       {
  212.     case '\0':
  213.     case '\n':
  214.     case 0x0D:
  215.       listtext[(i*(PREVIEW_WIDTH+1))+j] = ' ';
  216.       break;
  217.     default:
  218.       listtext[(i*(PREVIEW_WIDTH+1))+j] = (i*PREVIEW_WIDTH)+j;
  219.       break;
  220.       }
  221.     }
  222.     listtext[(i*(PREVIEW_WIDTH+1))+PREVIEW_WIDTH] = '\n';
  223.   }
  224.   listtext[((PREVIEW_WIDTH+1)*(256/PREVIEW_WIDTH))] = '\0';
  225.   SetGadgetAttrs(PreviewStr,PreviewWnd,NULL,
  226.     TEXTFIELD_Text,listtext,TAG_DONE);
  227.   ActivateGadget(PreviewStr,PreviewWnd,NULL);
  228. }
  229.  
  230. UBYTE *SaveFont(BOOL tables,BOOL preview)
  231. {
  232. char fontpath[256], filename[256], datestr[LEN_DATSTRING];
  233. ULONG filesize = 0, numchars, bitwidth = 0, i, offbit, hunkstart;
  234. struct DateTime dt;
  235. struct DiskFontHeader *dfh;
  236. struct FontContentsHeader *fch;
  237. ULONG *longptr, *relocstart;
  238. UBYTE *buffer, *mptr, *fontdataptr;
  239. struct charDef *fontlocptr;
  240. WORD *fontkernptr;
  241. BPTR fontfile, contfile, lock;
  242.  
  243. extern ULONG Proportional, Normal, Bold, Italic, ULine, Extended, Reversed;
  244. extern ULONG Height, Width, Baseline, Smear, Aspect;
  245. extern WORD SpaceTable[257], KernTable[257];
  246. extern BOOL DataChanged;
  247. extern char SavePath[256], FontName[256];
  248.  
  249.   strcpy(fontpath,SavePath);
  250.   AddPart(fontpath,FontName,256);
  251.   sprintf(filename,"%s/%ld",fontpath,Height);
  252.  
  253.   DateStamp(&(dt.dat_Stamp));
  254.   dt.dat_Format = FORMAT_CDN;
  255.   dt.dat_Flags = 0;
  256.   dt.dat_StrDay = NULL;
  257.   dt.dat_StrDate = datestr;
  258.   dt.dat_StrTime = NULL;
  259.   DateToStr(&dt);
  260.   while ((mptr = strchr(datestr,'-')) != NULL) *mptr = '.';
  261.  
  262.   numchars = LastChar-FirstChar+2;
  263.   filesize += 14*4;            /* Hunk structure */
  264.   filesize += sizeof(struct DiskFontHeader);
  265.   filesize += 4*4;            /* Relocatable addresses */
  266.   for (i = FirstChar; i < LastChar+1; i++)
  267.     bitwidth += (CharBuffer+i)->chr_Width;
  268.   bitwidth += (CharBuffer+256)->chr_Width;
  269.   if (bitwidth % 16 > 0) bitwidth = ((bitwidth/16)+1)*16;
  270.   filesize += (bitwidth/8)*Height;    /* Character data */
  271.   filesize += numchars*sizeof(struct charDef);
  272.   if (tables)
  273.   {
  274.     filesize += numchars*4;        /* Space and kern tables */
  275.     filesize += 2*4;            /* Table relocs */
  276.   }
  277.   if (filesize % 4 > 0) filesize = ((filesize/4)+1)*4;
  278.   if ((buffer = AllocVec(filesize,MEMF_CLEAR)) != NULL)
  279.   {
  280.     longptr = buffer;
  281.     *longptr++ = 0x000003F3;        /* Hunk structure */
  282.     *longptr++ = 0x00000000;
  283.     *longptr++ = 0x00000001;
  284.     *longptr++ = 0x00000000;
  285.     *longptr++ = 0x00000000;
  286.     *longptr++ = (filesize - ((tables ? 19 : 17)*4))/4;
  287.     *longptr++ = 0x000003E9;        /* Hunk size (twice) */
  288.     *longptr++ = (filesize - ((tables ? 19 : 17)*4))/4;
  289.     if (preview)
  290.       hunkstart = 0;
  291.     else
  292.       hunkstart = longptr;        /* All relocs relative to here */
  293.     *longptr++ = 0x70FF4E75;        /* MOVEQ #-1,D0 RTS */
  294.     relocstart = buffer+filesize-((9+(tables ? 2 : 0))*4);
  295.  
  296.     dfh = longptr;
  297.     dfh->dfh_DF.ln_Type = NT_FONT;
  298.     dfh->dfh_DF.ln_Name = (UBYTE *)((ULONG)dfh->dfh_Name-hunkstart);
  299.     dfh->dfh_FileID = DFH_ID;
  300.     sprintf(dfh->dfh_Name,"$VER: %s%d 39.0 (%s)",FontName,Height,datestr);
  301.  
  302.     fontdataptr = ((UBYTE *)dfh)+sizeof(struct DiskFontHeader);
  303.     fontlocptr = fontdataptr+((bitwidth/8)*Height);
  304.     if ((ULONG)fontlocptr % 2 > 0)
  305.       fontlocptr = (struct charDef *)((((ULONG)fontlocptr/2)+1)*2);
  306.     fontkernptr = (UBYTE *)fontlocptr + numchars*sizeof(struct charDef);
  307.  
  308.     tfh = &(dfh->dfh_TF);
  309.     tfh->tf_Message.mn_Node.ln_Type = NT_FONT;
  310.     tfh->tf_Message.mn_Node.ln_Name = dfh->dfh_DF.ln_Name;
  311.     tfh->tf_YSize = Height;
  312.     if (Normal == FALSE)
  313.     {
  314.       if (Bold) tfh->tf_Style |= FSF_BOLD;
  315.       if (Italic) tfh->tf_Style |= FSF_ITALIC;
  316.       if (ULine) tfh->tf_Style |= FSF_UNDERLINED;
  317.       if (Extended) tfh->tf_Style |= FSF_EXTENDED;
  318.     }
  319.     else tfh->tf_Style = FS_NORMAL;
  320.     tfh->tf_Flags = FPF_DESIGNED|FPF_DISKFONT;
  321.     if (Proportional) tfh->tf_Flags |= FPF_PROPORTIONAL;
  322.     if (Reversed) tfh->tf_Flags |= FPF_REVPATH;
  323.     switch (Aspect)
  324.     {
  325.       case 1:
  326.     tfh->tf_Flags |= FPF_TALLDOT;
  327.     break;
  328.       case 2:
  329.     tfh->tf_Flags |= FPF_WIDEDOT;
  330.     break;
  331.     }
  332.     tfh->tf_XSize = Width;
  333.     tfh->tf_Baseline = Baseline;
  334.     tfh->tf_BoldSmear = Smear;
  335.     tfh->tf_LoChar = FirstChar;
  336.     tfh->tf_HiChar = LastChar;
  337.     tfh->tf_CharData = (UBYTE *)((ULONG)fontdataptr-hunkstart);
  338.     tfh->tf_Modulo = bitwidth/8;
  339.     tfh->tf_CharLoc = (UBYTE *)((ULONG)fontlocptr-hunkstart);
  340.     if (tables)
  341.     {
  342.       tfh->tf_CharSpace = (UBYTE *)((ULONG)fontkernptr-hunkstart);
  343.       tfh->tf_CharKern =
  344.     (UBYTE *)((ULONG)fontkernptr+(numchars*2)-hunkstart);
  345.     }
  346.     for (i = FirstChar, offbit = 0; i < LastChar+1; i++)
  347.     {
  348.       WriteCharData(fontlocptr,fontdataptr,i-FirstChar,i,&offbit,bitwidth/8);
  349.       if (tables)
  350.       {
  351.     *(fontkernptr+(i-FirstChar)) = SpaceTable[i];
  352.     *(fontkernptr+(i-FirstChar+numchars)) = KernTable[i];
  353.       }
  354.     }
  355.     WriteCharData(fontlocptr,fontdataptr,numchars-1,256,&offbit,bitwidth/8);
  356.     if (tables)
  357.     {
  358.       *(fontkernptr+(numchars-1)) = SpaceTable[256];
  359.       *(fontkernptr+(numchars-1+numchars)) = KernTable[256];
  360.     }
  361.  
  362.     *relocstart++ = 0x000003EC;        /* Reloc structure */
  363.     *relocstart++ = 4 + (tables ? 2 : 0);
  364.     *relocstart++ = 0x00000000;
  365.     if (tables)
  366.     {
  367.       *relocstart++ = (ULONG)(&(tfh->tf_CharKern))-hunkstart;
  368.       *relocstart++ = (ULONG)(&(tfh->tf_CharSpace))-hunkstart;
  369.     }
  370.     *relocstart++ = (ULONG)(&(tfh->tf_CharLoc))-hunkstart;
  371.     *relocstart++ = (ULONG)(&(tfh->tf_CharData))-hunkstart;
  372.     *relocstart++ = (ULONG)(&(tfh->tf_Message.mn_Node.ln_Name))-hunkstart;
  373.     *relocstart++ = (ULONG)(&(dfh->dfh_DF.ln_Name))-hunkstart;
  374.     *relocstart++ = 0x00000000;
  375.     *relocstart++ = 0x000003F2;
  376.  
  377.     if (preview) return (buffer);
  378.  
  379.     WindowBusy(SaveWndObj);
  380.     lock = Lock(fontpath,ACCESS_READ);
  381.     WindowReady(SaveWndObj);
  382.     if (lock == 0)
  383.     {
  384.       if (SaveShowReq(GetString(msgSaveNoDir),GetString(msgSaveNoDirGadgets),
  385.     fontpath))
  386.       {
  387.         WindowBusy(SaveWndObj);
  388.         lock = CreateDir(fontpath);
  389.         WindowReady(SaveWndObj);
  390.     if (lock == 0)
  391.     {
  392.       SaveShowReq(GetString(msgSaveCreateError),GetString(msgCancel),
  393.         fontpath);
  394.       if (buffer) FreeVec(buffer);
  395.       return;
  396.     }
  397.     else UnLock(lock);
  398.       }
  399.       else
  400.       {
  401.     if (buffer) FreeVec(buffer);
  402.     return;
  403.       }
  404.     }
  405.     else UnLock(lock);
  406.  
  407.     WindowBusy(SaveWndObj);
  408.     lock = Lock(filename,ACCESS_READ);
  409.     WindowReady(SaveWndObj);
  410.     if (lock)
  411.     {
  412.       UnLock(lock);
  413.       if (!SaveShowReq(GetString(msgSaveWarnExists),
  414.     GetString(msgSaveWarnExistsGadgets),filename))
  415.       {
  416.     if (buffer) FreeVec(buffer);
  417.     return;
  418.       }
  419.     }
  420.  
  421.     WindowBusy(SaveWndObj);
  422.     fontfile = Open(filename,MODE_NEWFILE);
  423.     WindowReady(SaveWndObj);
  424.     if (fontfile)
  425.     {
  426.       WindowBusy(SaveWndObj);
  427.       Write(fontfile,buffer,filesize);
  428.       Close(fontfile);
  429.       DataChanged = FALSE;
  430.  
  431.       lock = Lock(SavePath,ACCESS_READ);
  432.       WindowReady(SaveWndObj);
  433.       if (lock != 0)
  434.       {
  435.     sprintf(filename,"%s.font",fontpath);
  436.     WindowBusy(SaveWndObj);
  437.     fch = NewFontContents(lock,FilePart(filename));
  438.     WindowReady(SaveWndObj);
  439.     if (fch != NULL)
  440.     {
  441.       WindowBusy(SaveWndObj);
  442.       contfile = Open(filename,MODE_NEWFILE);
  443.       WindowReady(SaveWndObj);
  444.       if (contfile != 0)
  445.       {
  446.         WindowBusy(SaveWndObj);
  447.         Write(contfile,fch,sizeof(struct FontContentsHeader)+
  448.           (fch->fch_NumEntries*sizeof(struct FontContents)));
  449.         Close(contfile);
  450.         WindowReady(SaveWndObj);
  451.       }
  452.       else SaveShowReq(GetString(msgSaveWriteHeader),
  453.         GetString(msgCancel),filename);
  454.       DisposeFontContents(fch);
  455.     }
  456.     else ShowReq(GetString(msgSaveCreateHeader),GetString(msgCancel));
  457.     UnLock(lock);
  458.       }
  459.     }
  460.     else SaveShowReq(GetString(msgSaveWriteData),GetString(msgCancel),
  461.       filename);
  462.   }
  463.   else SaveShowReq(GetString(msgSaveNoMemory),GetString(msgCancel));
  464.   if (buffer) FreeVec(buffer);
  465.   FlushAllFonts();
  466.   return (NULL);
  467. }
  468.  
  469. ULONG SaveShowReq(char *text,char *gadgets,...)
  470. {
  471. va_list va;
  472. struct EasyStruct req =
  473.   { sizeof(struct EasyStruct),0,NAME,NULL,NULL };
  474. ULONG retcode;
  475.  
  476.   if (SaveWnd == NULL) return (0);
  477.   WindowBusy(SaveWndObj);
  478.   req.es_TextFormat = text;
  479.   req.es_GadgetFormat = gadgets;
  480.   va_start(va,gadgets);
  481.   retcode = EasyRequestArgs(SaveWnd,&req,NULL,va);
  482.   va_end(va);
  483.   WindowReady(SaveWndObj);
  484.   return (retcode);
  485. }
  486.  
  487. void WriteCharData(struct charDef *cd, UBYTE *fontdataptr, ULONG dest,
  488.   ULONG src, ULONG *off, ULONG mod)
  489. {
  490. struct Character *chr;
  491. UBYTE *data;
  492. ULONG i,j,width,widthi,modi,offset;
  493.  
  494.   chr = CharBuffer+src;
  495.   data = (chr->chr_Data == NULL) ?
  496.     (CharBuffer+256)->chr_Data : chr->chr_Data;
  497.   width = chr->chr_Width;
  498.   offset = *off;
  499.   for (i = 0; i < chr->chr_Height; i++)
  500.   {
  501.     modi = mod*i;
  502.     widthi = width*i;
  503.     for (j = 0; j < width; j++)
  504.     {
  505.       if (*(data+widthi+j) == 1)
  506.     *(fontdataptr+modi+((offset+j)>>3)) |= 128>>((offset+j)&7);
  507.     }
  508.   }
  509.   (cd+dest)->charOffset = offset;
  510.   (cd+dest)->charBitWidth = width;
  511.   *off += width;
  512. }
  513.